﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;

using System.Collections.Generic;
using SmartProject.BusinessObjects;

namespace SmartProject.AppSpace
{
    public partial class WorkItem : UI.BasePage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                string workIdString = (string)Cache["WorkID"];
                if (String.IsNullOrEmpty(workIdString))
                {
                    Response.Redirect("~/AppSpace/MyPage.aspx");
                }
                else
                {
                    LblWorkId.Value = workIdString;
                    int workId = Convert.ToInt32(workIdString);
                    RefreshPage(workId);
                    BindMessages(new BusinessObjects.Message(), workId);
                    BindAttachments(new WorkAttachment(), workId);
                    BusinessObjects.User user = new SmartProject.BusinessObjects.User();
                    user.Populate(this.LstReceipiants);

                    System.Text.StringBuilder fileUploadScript =
                        new System.Text.StringBuilder("javascript:");

                    string line = "var fil{0} = document.getElementById('{1}'); if(fil{0}.length > 0) {{ fil{0}.select();n{0}=fil{0}.createTextRange();n{0}.execCommand('delete'); }}";
                    fileUploadScript.Append(String.Format(line, "0", this.FupUploader1.ClientID));
                    fileUploadScript.Append(String.Format(line, "1", this.FupUploader2.ClientID));
                    fileUploadScript.Append(String.Format(line, "2", this.FupUploader3.ClientID));
                    fileUploadScript.Append(String.Format(line, "3", this.FupUploader4.ClientID));
                    fileUploadScript.Append(" return true;");
                    this.BtnCancelSaveAttachments.OnClientClick = fileUploadScript.ToString();

                    TimeType timeType = new TimeType();
                    timeType.Populate(this.DrpActual);
                }
            }
        }

        private void SetToLabel(Object objText, Label lbl)
        {
            if (objText != null)
            {
                string value = objText.ToString();
                if (lbl != null)
                {
                    lbl.Text = value;
                }
            }
            else
            {
                if (lbl != null)
                {
                    lbl.Text = "N/A";
                }
            }
        }

        protected void BtnSaveAttachments_Click(object sender, EventArgs e)
        {
            int workId = PageWorkId;
            WorkAttachment workAttachment = new WorkAttachment();
            SaveAttachment(workAttachment, workId, FupUploader1);
            SaveAttachment(workAttachment, workId, FupUploader2);
            SaveAttachment(workAttachment, workId, FupUploader3);
            SaveAttachment(workAttachment, workId, FupUploader4);
            BindAttachments(workAttachment, workId);
        }

        private void SaveAttachment(WorkAttachment workAttachment, int workId, FileUpload fileUpload)
        {
            if (fileUpload.HasFile)
            {
                workAttachment.SetAttribute("OwnerId", base.UserId);
                workAttachment.SetAttribute("ReferenceId", workId);
                workAttachment.SetAttribute("FiletypeId",
                    workAttachment.AttachmentFileType.GetFileTypeId(fileUpload.FileName));
                workAttachment.SetAttribute("Filename", fileUpload.FileName);
                workAttachment.SetAttribute("Filecontent", fileUpload.FileBytes);
                workAttachment.Save();
            }
        }

        protected void BtnSaveMessage_Click(object sender, EventArgs e)
        {
            this.LblError.Text = String.Empty;
            bool refreshPage = false;
            int workId = PageWorkId;
            Work work = new Work();
            if (this.LblMessageTitle.Text == "Update status")
            {
                switch (this.DrpOptions.SelectedValue)
                {
                    case "In Progress":
                        work.SetAttribute("WorkId", workId);
                        work.StartWork();
                        SetPage(String.Format("Work ID: {0}", workId.ToString()), "In Progress");
                        if (String.IsNullOrEmpty(this.TxtNewNotes.Content))
                        {
                            this.TxtNewNotes.Content = "Work is updated to In-Progress Status without any comments.";
                        }
                        break;

                    case "On Hold":
                        work.SetAttribute("WorkId", workId);
                        work.HoldWork();
                        SetPage(String.Format("Work ID: {0}", workId.ToString()), "On Hold");
                        if (String.IsNullOrEmpty(this.TxtNewNotes.Content))
                        {
                            this.TxtNewNotes.Content = "Work is updated to On-Hold Status without any comments.";
                        }
                        break;

                    case "Internal QA":
                    case "Client QA":
                        try
                        {
                            work.SetAttribute("ActualTime", this.TxtActual.Text);
                            work.SetAttribute("ActualTimeTypeId", this.DrpActual.SelectedValue);
                            work.SetAttribute("WorkId", PageWorkId);
                            work.SetAttribute("StatusId", work.Statuses.GetId(this.DrpOptions.SelectedValue, false));
                        }
                        catch (Exceptions.RequiredDataParameter requiredDataParameter)
                        {
                            this.LblError.Text = requiredDataParameter.Message;
                            this.PopAddMessage.Show();
                            return;
                        }

                        if (String.IsNullOrEmpty(this.TxtNewNotes.Content))
                        {
                            this.TxtNewNotes.Content = String.Format("Work is updated to {0} Status without any comments.", this.DrpOptions.SelectedValue);
                        }

                        try
                        {
                            work.Complete();
                        }
                        catch (Exceptions.BusinessRuleViolation businessRuleViolation)
                        {
                            this.LblError.Text = businessRuleViolation.Message;
                            this.PopAddMessage.Show();
                            return;
                        }
                        refreshPage = true;
                        break;
                    case "Approved":
                        work.SetAttribute("WorkId", PageWorkId);
                        try
                        {
                            work.Approve();
                        }
                        catch (Exceptions.BusinessRuleViolation businessRuleViolation)
                        {
                            this.LblError.Text = businessRuleViolation.Message;
                            return;
                        }
                        if (String.IsNullOrEmpty(this.TxtNewNotes.Content))
                        {
                            this.TxtNewNotes.Content = String.Format("Work is updated to {0} Status without any comments.", this.DrpOptions.SelectedValue);
                        }
                        refreshPage = true;
                        break;
                    case "InComplete":
                        work.SetAttribute("WorkId", workId);
                        work.SetAttribute("UserId", base.UserId);
                        try
                        {
                            work.InComplete();
                        }
                        catch (Exceptions.BusinessRuleViolation businessRuleViolation)
                        {
                            this.LblError.Text = businessRuleViolation.Message;
                            return;
                        }
                        if (String.IsNullOrEmpty(this.TxtNewNotes.Content))
                        {
                            this.TxtNewNotes.Content = String.Format("Work is Incomplete. Work has been reset back to In-Progress status without any comments.", this.DrpOptions.SelectedValue);
                        }
                        refreshPage = true;
                        break;

                    case "Discard":
                        work.SetAttribute("WorkId", PageWorkId);
                        try
                        {
                            work.Discard();
                        }
                        catch (Exceptions.BusinessRuleViolation businessRuleViolation)
                        {
                            this.LblError.Text = businessRuleViolation.Message;
                            return;
                        }
                        if (String.IsNullOrEmpty(this.TxtNewNotes.Content))
                        {
                            this.TxtNewNotes.Content = String.Format("Work is discarded without any comments.", this.DrpOptions.SelectedValue);
                        }
                        refreshPage = true;
                        break;
                }
            }

            System.Collections.Generic.List<int> userIdList =
                new System.Collections.Generic.List<int>();

            for (int i = 0; i < this.LstReceipiants.Items.Count; i++)
            {
                ListItem item = this.LstReceipiants.Items[i];
                if (item.Selected)
                {
                    userIdList.Add(Convert.ToInt32(item.Value));
                }
            }
            BusinessObjects.Message message = new BusinessObjects.Message();
            message.SetAttribute("ReferenceObjectId", workId);
            message.SetAttribute("OwnerId", base.UserId);

            try
            {
                message.SetAttribute("Description", this.TxtNewNotes.Content);
            }
            catch (Exceptions.RequiredDataParameter requiredDataParameter)
            {
                this.LblError.Text = requiredDataParameter.Message;
                return;
            }

            if (userIdList.Count > 0)
            {
                message.SaveWorkMessage(userIdList.ToArray());
            }
            else
            {
                message.Save();
            }
            BindMessages(message, workId);
            this.LstReceipiants.ClearSelection();
            this.TxtNewNotes.Content = "";
            this.LblMessageTitle.Text = "New Message";

            if (refreshPage)
            {
                RefreshPage(work);
            }
        }

        protected void BtnRemoveMessage_Click(object sender, EventArgs e)
        {
            ImageButton btn = (ImageButton)sender;
            BusinessObjects.Message message = new BusinessObjects.Message();
            message.SetAttribute("MessageId", Convert.ToInt32(btn.CommandArgument));
            message.Remove();
            BindMessages(message, PageWorkId);
        }

        /// <summary>
        /// Gets the work Id set on this page.
        /// </summary>
        private int PageWorkId
        {
            get
            {
                return Convert.ToInt32(LblWorkId.Value);
            }
        }

        protected void DpgNotes_PreRender(object sender, EventArgs e)
        {
            BindMessages(new BusinessObjects.Message(), PageWorkId);
        }

        private void BindMessages(BusinessObjects.Message message, int workId)
        {
            message.SetAttribute("ReferenceObjectId", workId);
            this.LstMessages.DataSource = message.LoadWorkMessages();
            this.LstMessages.DataBind();
        }

        private void BindAttachments(WorkAttachment workAttachment, int workId)
        {
            workAttachment.SetAttribute("ReferenceId", workId);
            System.Data.DataTable attachments = workAttachment.LoadAttachments();
            // This is used to insert into message.
            this.DrpAttachments.Items.Clear();
            // This is use to fire the link to download files.
            this.DrpAttachmentsDownload.Items.Clear();

            if (attachments != null)
            {
                this.BtnRemoveAttachment.Visible = true;
                this.DrpAttachmentsDownload.Visible = true;
                this.BtnDownload.Visible = true;

                string pageName = VirtualPathUtility.GetFileName(Request.FilePath);
                string url = Request.Url.OriginalString;
                url = url.Substring(0, url.Length - pageName.Length);
                if (!url.EndsWith("/"))
                {
                    url += "/";
                }
                System.Text.StringBuilder imagePath =
                    new System.Text.StringBuilder();
                imagePath.Append("<a href='");
                imagePath.Append(url);
                imagePath.Append("Download.aspx?ID={1}' target='_blank'><img src='");
                imagePath.Append(url);
                imagePath.Append("Download.aspx?ID={0}' Width='100px' Height='100px' border='0' /></a>");
                string imagePathString = imagePath.ToString();

                System.Text.StringBuilder downloadPath =
                    new System.Text.StringBuilder();
                downloadPath.Append("<a href='");
                downloadPath.Append(url);
                downloadPath.Append("Download.aspx?ID={0}&Action=Download'>{1}</a>");
                string downloadPathString = downloadPath.ToString();

                for (int i = 0; i < attachments.Rows.Count; i++)
                {
                    DataRow row = attachments.Rows[i];
                    string fileName = (string)row["Filename"];
                    int attachmentId = (int)row["AttachmentId"];
                    this.DrpAttachmentsDownload.Items.Add(new ListItem(fileName,
                        attachmentId.ToString()));

                    if (workAttachment.AttachmentFileType.IsImageFile((int)row["FiletypeId"]))
                    {
                        this.DrpAttachments.Items.Add(new ListItem(fileName,
                            String.Format(imagePathString, attachmentId.ToString(),
                            attachmentId.ToString())));
                    }
                    else
                    {
                        this.DrpAttachments.Items.Add(new ListItem(fileName,
                            String.Format(downloadPathString, attachmentId.ToString(), fileName)));
                    }
                }
            }
            else
            {
                this.DrpAttachmentsDownload.Visible = false;
                this.BtnRemoveAttachment.Visible = false;
                this.BtnDownload.Visible = false;
            }
        }

        protected void BtnRemoveAttachment_Click(object sender, EventArgs e)
        {
            WorkAttachment workAttachment = new WorkAttachment();
            workAttachment.SetAttribute("ReferenceId",
                Convert.ToInt32(this.DrpAttachmentsDownload.SelectedValue));
            workAttachment.Remove();
            BindAttachments(workAttachment, Convert.ToInt32(this.LblWorkId.Value));
        }

        protected void BtnDownload_Click(object sender, EventArgs e)
        {
            Response.Redirect("Download.aspx?ID="
                + this.DrpAttachmentsDownload.SelectedValue + "&Action=Download");
        }

        protected void BtnInsertAttachmentText_Click(object sender, EventArgs e)
        {
            this.TxtNewNotes.Content += this.DrpAttachments.SelectedValue;
        }

        protected void BtnCancelMessage_Click(object sender, ImageClickEventArgs e)
        {
            this.LstReceipiants.ClearSelection();
            this.TxtNewNotes.Content = "";
            this.LblMessageTitle.Text = "New Message";
            this.LblText1.Visible = false;
            this.LblText2.Visible = false;
            this.TxtActual.Visible = false;
            this.DrpActual.Visible = false;
            this.DrpOptions.Visible = false;
            this.PopAddMessage.Hide();
        }

        protected void BtnCancelSaveAttachments_Click(object sender, ImageClickEventArgs e)
        {
            this.PopManageAttachments.Hide();
        }

        protected void BtnUpdateStatus_Click(object sender, ImageClickEventArgs e)
        {
            this.LblMessageTitle.Text = "Update status";
            this.DrpOptions.Items.Clear();
            this.DrpOptions.Items.Insert(0, new ListItem("Select one", ""));
            switch (base.Description)
            {
                case "Assigned":
                    this.DrpOptions.Items.Add(new ListItem("In Progress", "In Progress"));
                    this.DrpOptions.Items.Add(new ListItem("Discard", "Discard"));
                    this.DrpOptions.Visible = true;
                    this.LblText1.Visible = false;
                    this.LblText2.Visible = true;
                    this.TxtActual.Visible = false;
                    this.DrpActual.Visible = false;
                    break;
                case "In Progress":
                    this.DrpOptions.Visible = true;
                    this.LblText1.Visible = true;
                    this.LblText2.Visible = true;
                    this.TxtActual.Visible = true;
                    this.DrpActual.Visible = true;
                    this.DrpOptions.Items.Add(new ListItem("On Hold", "On Hold"));
                    this.DrpOptions.Items.Add(new ListItem("Internal QA", "Internal QA"));
                    this.DrpOptions.Items.Add(new ListItem("Client QA", "Client QA"));
                    this.DrpOptions.Items.Add(new ListItem("Approved", "Approved"));
                    this.DrpOptions.Items.Add(new ListItem("Discard", "Discard"));
                    break;
                case "On Hold":
                    this.DrpOptions.Visible = true;
                    this.LblText1.Visible = true;
                    this.LblText2.Visible = true;
                    this.TxtActual.Visible = true;
                    this.DrpActual.Visible = true;
                    this.DrpOptions.Items.Add(new ListItem("In Progress", "In Progress"));
                    this.DrpOptions.Items.Add(new ListItem("Discard", "Discard"));
                    break;
                case "Internal QA":
                    this.DrpOptions.Visible = true;
                    this.LblText1.Visible = true;
                    this.LblText2.Visible = true;
                    this.TxtActual.Visible = true;
                    this.DrpActual.Visible = true;
                    this.DrpOptions.Items.Add(new ListItem("Client QA", "Client QA"));
                    this.DrpOptions.Items.Add(new ListItem("Approved", "Approved"));
                    this.DrpOptions.Items.Add(new ListItem("InComplete", "InComplete"));
                    this.DrpOptions.Items.Add(new ListItem("Discard", "Discard"));
                    break;
                case "Client QA":
                    this.DrpOptions.Visible = true;
                    this.LblText1.Visible = true;
                    this.LblText2.Visible = true;
                    this.TxtActual.Visible = true;
                    this.DrpActual.Visible = true;
                    this.DrpOptions.Items.Add(new ListItem("Approved", "Approved"));
                    this.DrpOptions.Items.Add(new ListItem("InComplete", "InComplete"));
                    this.DrpOptions.Items.Add(new ListItem("Discard", "Discard"));
                    break;
                default:
                    this.LblText1.Visible = false;
                    this.LblText2.Visible = false;
                    this.TxtActual.Visible = false;
                    this.DrpActual.Visible = false;
                    this.DrpOptions.Visible = false;
                    break;
            }

            this.PopAddMessage.Show();
        }

        public override void RefreshPage(object obj)
        {
            int workId;
            Work work;
            if (obj.GetType() == typeof(Work))
            {
                work = (Work)obj;
                workId = PageWorkId;
            }
            else
            {
                work = new Work();
                workId = (int)obj;
            }

            work.SetAttribute("WorkId", workId);
            work.Load();

            CtlAddEditWork.Initialize(work);
            this.SetPage(String.Format("Work ID: {0}", workId.ToString()), work.Statuses.Value);
            // You will not be able to change status when the work has not been
            // assigned or when it is already approved.
            if (base.Description == "New" || base.Description == "Approved")
            {
                this.BtnUpdateStatus.Visible = false;
                if (base.Description == "Approved")
                {
                    this.BtnDelete.Visible = false;
                    this.BtnEdit.Visible = false;
                }
            }
            else
            {
                this.BtnUpdateStatus.Visible = true;
            }

            this.LblWorkCategory.Text = work.Categories.GetValue(
                (int)work.GetAttributeValue("CategoryId"));
            this.LblDescText.Text = work.GetAttributeValue("Description").ToString();
            BusinessObjects.Product product = new Product();
            this.LblProduct.Text = work.GetAttributeValue("ProductName").ToString();
            this.LblOwner.Text = work.GetAttributeValue("OwnerName").ToString();

            DateTime dueDate = (DateTime)work.GetAttributeValue("DueDate");
            this.LblDueBy.Text = dueDate.ToLongDateString();
            TimeSpan length = dueDate - DateTime.Today;
            int days = length.Days;
            if (days == 0)
            {
                this.LblDueBy.ForeColor = System.Drawing.Color.Red;
                this.LblDueByDescription.ForeColor = System.Drawing.Color.Red;
                this.LblDueByDescription.Text = "Due today.";
            }
            else if (days > 0)
            {
                this.LblDueByDescription.Text = String.Format("{0} days remaining.", days.ToString());
            }
            else if (days < 0)
            {
                this.LblDueBy.ForeColor = System.Drawing.Color.Red;
                this.LblDueByDescription.ForeColor = System.Drawing.Color.Red;
                this.LblDueByDescription.Text = String.Format("Past due by {0} day(s).",
                    Math.Abs(days).ToString());
            }

            DateTime created = (DateTime)work.GetAttributeValue("Created");
            this.LblCreated.Text = created.ToString();

            work.Priorities.SetLabel(this.LblPriority,
                work.GetAttributeValue("PrioritySeverityId").ToString());

            object objWork = work.GetAttributeValue("EstTime");
            SetToLabel(objWork, this.LblEst);
            if (objWork != null)
            {
                string timeTypeString = work.EstTimeType.GetValue((int)work.GetAttributeValue("EstTimeTypeId"));
                this.LblEst.Text += " " + timeTypeString;
            }

            objWork = work.GetAttributeValue("ActualTime");
            SetToLabel(objWork, this.LblActual);
            if (objWork != null)
            {
                this.TxtActual.Text = objWork.ToString();
                int actualTimeTypeId = (int)work.GetAttributeValue("ActualTimeTypeId");
                this.DrpActual.SelectedValue = actualTimeTypeId.ToString();
                this.LblActual.Text += " " + work.ActualTimeType.GetValue(actualTimeTypeId);
            }

            objWork = work.GetAttributeValue("Assigned");
            SetToLabel(objWork, this.LblAssigned);
            objWork = work.GetAttributeValue("Approved");
            SetToLabel(objWork, this.LblApproved);
            objWork = work.GetAttributeValue("Completed");
            SetToLabel(objWork, this.LblCompleted);
            objWork = work.GetAttributeValue("SprintName");
            SetToLabel(objWork, this.LblSprint);
            objWork = work.GetAttributeValue("DeveloperName");
            SetToLabel(objWork, this.LblDeveloperName);
        }

        protected void BtnDelete_Click(object sender, EventArgs e)
        {
            this.ClearErrorOrWarning();
            Work work = new Work();
            work.SetAttribute("WorkId", PageWorkId);
            try
            {
                work.Remove();
            }
            catch (Exceptions.BusinessRuleViolation businessRuleViolation)
            {
                this.DisplayErrorOrWarning(businessRuleViolation.Message);
                return;
            }
            Response.Redirect("~/AppSpace/MyPage.aspx", true);
        }

        public override AjaxControlToolkit.ModalPopupExtender Popup(string name)
        {
            return this.PopEditWork;
        }
    }
}
